<template>
  <div class="snake-game-container">
    <div class="game-header">
      <h1>🐍 贪吃蛇游戏</h1>
      <div class="game-stats">
        <div class="stat-item">
          <span class="label">分数:</span>
          <span class="value">{{ score }}</span>
        </div>
        <div class="stat-item">
          <span class="label">最高分:</span>
          <span class="value">{{ highScore }}</span>
        </div>
        <div class="stat-item">
          <span class="label">长度:</span>
          <span class="value">{{ snake.length }}</span>
        </div>
      </div>
    </div>

    <div class="game-controls">
      <button 
        @click="startGame" 
        :disabled="gameRunning"
        class="control-btn start-btn"
      >
        {{ gameRunning ? '游戏进行中' : '开始游戏' }}
      </button>
      <button 
        @click="pauseGame" 
        :disabled="!gameRunning"
        class="control-btn pause-btn"
      >
        {{ gamePaused ? '继续' : '暂停' }}
      </button>
      <button 
        @click="resetGame"
        class="control-btn reset-btn"
      >
        重新开始
      </button>
      <div class="speed-control">
        <label>速度:</label>
        <select v-model="gameSpeed" @change="updateSpeed">
          <option value="200">慢速</option>
          <option value="150">中速</option>
          <option value="100">快速</option>
          <option value="80">极速</option>
        </select>
      </div>
    </div>

    <div class="game-board-container">
      <div 
        class="game-board" 
        :style="{ 
          gridTemplateColumns: `repeat(${boardSize}, 1fr)`,
          gridTemplateRows: `repeat(${boardSize}, 1fr)`
        }"
        @keydown="handleKeyPress"
        tabindex="0"
        ref="gameBoard"
      >
        <!-- 游戏网格 -->
        <div
          v-for="(cell, index) in gameGrid"
          :key="index"
          :class="[
            'game-cell',
            {
              'snake-head': isSnakeHead(index),
              'snake-body': isSnakeBody(index),
              'food': isFood(index),
              'wall': isWall(index)
            }
          ]"
          :style="getCellStyle(index)"
        >
          <div v-if="isSnakeHead(index)" class="snake-head-content">
            {{ getSnakeHeadDirection() }}
          </div>
          <div v-if="isFood(index)" class="food-content">
            🍎
          </div>
        </div>
      </div>

      <!-- 游戏状态覆盖层 -->
      <div v-if="!gameRunning && !gameOver" class="game-overlay start-overlay">
        <div class="overlay-content">
          <h2>🎮 准备开始</h2>
          <p>使用 WASD 或方向键控制蛇的移动</p>
          <p>吃到红苹果可以增长身体和得分</p>
          <button @click="startGame" class="overlay-btn">开始游戏</button>
        </div>
      </div>

      <div v-if="gamePaused" class="game-overlay pause-overlay">
        <div class="overlay-content">
          <h2>⏸️ 游戏暂停</h2>
          <p>按空格键或点击继续按钮恢复游戏</p>
          <button @click="pauseGame" class="overlay-btn">继续游戏</button>
        </div>
      </div>

      <div v-if="gameOver" class="game-overlay game-over-overlay">
        <div class="overlay-content">
          <h2>💀 游戏结束</h2>
          <p>最终分数: <strong>{{ score }}</strong></p>
          <p v-if="isNewHighScore" class="new-record">🎉 新纪录！</p>
          <div class="game-over-stats">
            <div>游戏时长: {{ formatTime(gameTime) }}</div>
            <div>蛇的长度: {{ snake.length }}</div>
            <div>食物数量: {{ foodEaten }}</div>
          </div>
          <button @click="resetGame" class="overlay-btn">重新开始</button>
        </div>
      </div>
    </div>

    <div class="game-instructions">
      <h3>🎮 游戏说明</h3>
      <div class="instructions-grid">
        <div class="instruction-item">
          <span class="key">W ↑</span>
          <span class="action">向上移动</span>
        </div>
        <div class="instruction-item">
          <span class="key">S ↓</span>
          <span class="action">向下移动</span>
        </div>
        <div class="instruction-item">
          <span class="key">A ←</span>
          <span class="action">向左移动</span>
        </div>
        <div class="instruction-item">
          <span class="key">D →</span>
          <span class="action">向右移动</span>
        </div>
        <div class="instruction-item">
          <span class="key">空格</span>
          <span class="action">暂停/继续</span>
        </div>
        <div class="instruction-item">
          <span class="key">R</span>
          <span class="action">重新开始</span>
        </div>
      </div>
    </div>

    <!-- 粒子效果 -->
    <div class="particles-container">
      <div
        v-for="particle in particles"
        :key="particle.id"
        class="particle"
        :style="particle.style"
      ></div>
    </div>
  </div>
</template>

<script>
import { ref, reactive, onMounted, onUnmounted, computed, nextTick } from 'vue'

export default {
  name: 'SnakeGame',
  setup() {
    // 游戏配置
    const boardSize = ref(20)
    const gameSpeed = ref(150)
    
    // 游戏状态
    const gameRunning = ref(false)
    const gamePaused = ref(false)
    const gameOver = ref(false)
    const score = ref(0)
    const highScore = ref(parseInt(localStorage.getItem('snakeHighScore') || '0'))
    const gameTime = ref(0)
    const foodEaten = ref(0)
    const isNewHighScore = ref(false)
    
    // 游戏对象
    const snake = ref([{ x: 10, y: 10 }])
    const direction = ref({ x: 1, y: 0 })
    const nextDirection = ref({ x: 1, y: 0 })
    const food = ref({ x: 15, y: 15 })
    const particles = ref([])
    
    // 游戏循环
    let gameLoop = null
    let gameTimer = null
    
    // 游戏板引用
    const gameBoard = ref(null)
    
    // 计算属性
    const gameGrid = computed(() => {
      return Array(boardSize.value * boardSize.value).fill(0)
    })
    
    // 方法
    const getIndex = (x, y) => y * boardSize.value + x
    
    const isSnakeHead = (index) => {
      const head = snake.value[0]
      return getIndex(head.x, head.y) === index
    }
    
    const isSnakeBody = (index) => {
      return snake.value.slice(1).some(segment => 
        getIndex(segment.x, segment.y) === index
      )
    }
    
    const isFood = (index) => {
      return getIndex(food.value.x, food.value.y) === index
    }
    
    const isWall = (index) => {
      const x = index % boardSize.value
      const y = Math.floor(index / boardSize.value)
      return x === 0 || x === boardSize.value - 1 || y === 0 || y === boardSize.value - 1
    }
    
    const getCellStyle = (index) => {
      const snakeIndex = snake.value.findIndex(segment => 
        getIndex(segment.x, segment.y) === index
      )
      
      if (snakeIndex >= 0) {
        const opacity = 1 - (snakeIndex * 0.1)
        return {
          backgroundColor: snakeIndex === 0 ? '#2ecc71' : '#27ae60',
          opacity: Math.max(opacity, 0.3)
        }
      }
      
      return {}
    }
    
    const getSnakeHeadDirection = () => {
      const dir = direction.value
      if (dir.x === 1) return '→'
      if (dir.x === -1) return '←'
      if (dir.y === 1) return '↓'
      if (dir.y === -1) return '↑'
      return '→'
    }
    
    const generateFood = () => {
      let newFood
      do {
        newFood = {
          x: Math.floor(Math.random() * (boardSize.value - 2)) + 1,
          y: Math.floor(Math.random() * (boardSize.value - 2)) + 1
        }
      } while (snake.value.some(segment => 
        segment.x === newFood.x && segment.y === newFood.y
      ))
      
      food.value = newFood
      createFoodParticles(newFood.x, newFood.y)
    }
    
    const createFoodParticles = (x, y) => {
      const cellSize = 25
      const boardRect = gameBoard.value?.getBoundingClientRect()
      if (!boardRect) return
      
      for (let i = 0; i < 8; i++) {
        const particle = {
          id: Date.now() + i,
          style: {
            position: 'absolute',
            left: `${boardRect.left + x * cellSize + cellSize / 2}px`,
            top: `${boardRect.top + y * cellSize + cellSize / 2}px`,
            width: '4px',
            height: '4px',
            backgroundColor: '#e74c3c',
            borderRadius: '50%',
            pointerEvents: 'none',
            animation: `particle-${i} 0.6s ease-out forwards`
          }
        }
        particles.value.push(particle)
        
        setTimeout(() => {
          particles.value = particles.value.filter(p => p.id !== particle.id)
        }, 600)
      }
    }
    
    const moveSnake = () => {
      if (!gameRunning.value || gamePaused.value) return
      
      direction.value = { ...nextDirection.value }
      const head = { ...snake.value[0] }
      head.x += direction.value.x
      head.y += direction.value.y
      
      // 检查碰撞
      if (checkCollision(head)) {
        endGame()
        return
      }
      
      snake.value.unshift(head)
      
      // 检查是否吃到食物
      if (head.x === food.value.x && head.y === food.value.y) {
        score.value += 10
        foodEaten.value++
        generateFood()
        createEatEffect(head.x, head.y)
      } else {
        snake.value.pop()
      }
    }
    
    const checkCollision = (head) => {
      // 撞墙
      if (head.x <= 0 || head.x >= boardSize.value - 1 || 
          head.y <= 0 || head.y >= boardSize.value - 1) {
        return true
      }
      
      // 撞自己
      return snake.value.some(segment => 
        segment.x === head.x && segment.y === head.y
      )
    }
    
    const createEatEffect = (x, y) => {
      // 创建吃食物的粒子效果
      createFoodParticles(x, y)
    }
    
    const handleKeyPress = (event) => {
      if (!gameRunning.value) return
      
      const key = event.key.toLowerCase()
      
      switch (key) {
        case 'w':
        case 'arrowup':
          if (direction.value.y !== 1) {
            nextDirection.value = { x: 0, y: -1 }
          }
          break
        case 's':
        case 'arrowdown':
          if (direction.value.y !== -1) {
            nextDirection.value = { x: 0, y: 1 }
          }
          break
        case 'a':
        case 'arrowleft':
          if (direction.value.x !== 1) {
            nextDirection.value = { x: -1, y: 0 }
          }
          break
        case 'd':
        case 'arrowright':
          if (direction.value.x !== -1) {
            nextDirection.value = { x: 1, y: 0 }
          }
          break
        case ' ':
          pauseGame()
          break
        case 'r':
          resetGame()
          break
      }
      
      event.preventDefault()
    }
    
    const startGame = () => {
      if (gameRunning.value) return
      
      gameRunning.value = true
      gamePaused.value = false
      gameOver.value = false
      
      gameLoop = setInterval(moveSnake, gameSpeed.value)
      gameTimer = setInterval(() => {
        gameTime.value++
      }, 1000)
      
      nextTick(() => {
        gameBoard.value?.focus()
      })
    }
    
    const pauseGame = () => {
      if (!gameRunning.value) return
      
      gamePaused.value = !gamePaused.value
      
      if (gamePaused.value) {
        clearInterval(gameLoop)
        clearInterval(gameTimer)
      } else {
        gameLoop = setInterval(moveSnake, gameSpeed.value)
        gameTimer = setInterval(() => {
          gameTime.value++
        }, 1000)
        nextTick(() => {
          gameBoard.value?.focus()
        })
      }
    }
    
    const resetGame = () => {
      clearInterval(gameLoop)
      clearInterval(gameTimer)
      
      gameRunning.value = false
      gamePaused.value = false
      gameOver.value = false
      score.value = 0
      gameTime.value = 0
      foodEaten.value = 0
      isNewHighScore.value = false
      
      snake.value = [{ x: 10, y: 10 }]
      direction.value = { x: 1, y: 0 }
      nextDirection.value = { x: 1, y: 0 }
      generateFood()
      particles.value = []
    }
    
    const endGame = () => {
      clearInterval(gameLoop)
      clearInterval(gameTimer)
      
      gameRunning.value = false
      gameOver.value = true
      
      // 检查是否创造新纪录
      if (score.value > highScore.value) {
        highScore.value = score.value
        isNewHighScore.value = true
        localStorage.setItem('snakeHighScore', score.value.toString())
      }
    }
    
    const updateSpeed = () => {
      if (gameRunning.value && !gamePaused.value) {
        clearInterval(gameLoop)
        gameLoop = setInterval(moveSnake, gameSpeed.value)
      }
    }
    
    const formatTime = (seconds) => {
      const mins = Math.floor(seconds / 60)
      const secs = seconds % 60
      return `${mins}:${secs.toString().padStart(2, '0')}`
    }
    
    // 生命周期
    onMounted(() => {
      generateFood()
      document.addEventListener('keydown', handleKeyPress)
    })
    
    onUnmounted(() => {
      clearInterval(gameLoop)
      clearInterval(gameTimer)
      document.removeEventListener('keydown', handleKeyPress)
    })
    
    return {
      // 响应式数据
      boardSize,
      gameSpeed,
      gameRunning,
      gamePaused,
      gameOver,
      score,
      highScore,
      gameTime,
      foodEaten,
      isNewHighScore,
      snake,
      direction,
      food,
      particles,
      gameBoard,
      
      // 计算属性
      gameGrid,
      
      // 方法
      isSnakeHead,
      isSnakeBody,
      isFood,
      isWall,
      getCellStyle,
      getSnakeHeadDirection,
      handleKeyPress,
      startGame,
      pauseGame,
      resetGame,
      updateSpeed,
      formatTime
    }
  }
}
</script>

<style scoped>
.snake-game-container {
  max-width: 1200px;
  margin: 0 auto;
  padding: 20px;
  font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  min-height: 100vh;
  color: white;
}

.game-header {
  text-align: center;
  margin-bottom: 30px;
}

.game-header h1 {
  font-size: 3em;
  margin-bottom: 20px;
  text-shadow: 2px 2px 4px rgba(0,0,0,0.3);
  background: linear-gradient(45deg, #f093fb, #f5576c, #4facfe, #00f2fe);
  background-size: 400% 400%;
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
  background-clip: text;
  animation: gradientShift 3s ease infinite;
}

@keyframes gradientShift {
  0%, 100% { background-position: 0% 50%; }
  50% { background-position: 100% 50%; }
}

.game-stats {
  display: flex;
  justify-content: center;
  gap: 30px;
  flex-wrap: wrap;
}

.stat-item {
  background: rgba(255,255,255,0.1);
  padding: 15px 25px;
  border-radius: 15px;
  backdrop-filter: blur(10px);
  border: 1px solid rgba(255,255,255,0.2);
}

.stat-item .label {
  font-weight: 600;
  margin-right: 10px;
}

.stat-item .value {
  font-size: 1.2em;
  font-weight: bold;
  color: #f1c40f;
}

.game-controls {
  display: flex;
  justify-content: center;
  align-items: center;
  gap: 15px;
  margin-bottom: 30px;
  flex-wrap: wrap;
}

.control-btn {
  padding: 12px 24px;
  border: none;
  border-radius: 25px;
  font-size: 16px;
  font-weight: 600;
  cursor: pointer;
  transition: all 0.3s ease;
  backdrop-filter: blur(10px);
  border: 1px solid rgba(255,255,255,0.2);
}

.start-btn {
  background: linear-gradient(45deg, #2ecc71, #27ae60);
  color: white;
}

.pause-btn {
  background: linear-gradient(45deg, #f39c12, #e67e22);
  color: white;
}

.reset-btn {
  background: linear-gradient(45deg, #e74c3c, #c0392b);
  color: white;
}

.control-btn:hover:not(:disabled) {
  transform: translateY(-2px);
  box-shadow: 0 5px 15px rgba(0,0,0,0.3);
}

.control-btn:disabled {
  opacity: 0.6;
  cursor: not-allowed;
}

.speed-control {
  display: flex;
  align-items: center;
  gap: 10px;
  background: rgba(255,255,255,0.1);
  padding: 10px 15px;
  border-radius: 15px;
  backdrop-filter: blur(10px);
}

.speed-control select {
  padding: 5px 10px;
  border: none;
  border-radius: 8px;
  background: rgba(255,255,255,0.9);
  color: #333;
}

.game-board-container {
  position: relative;
  display: flex;
  justify-content: center;
  margin-bottom: 30px;
}

.game-board {
  display: grid;
  gap: 1px;
  background: #2c3e50;
  border: 3px solid #34495e;
  border-radius: 15px;
  padding: 10px;
  box-shadow: 0 10px 30px rgba(0,0,0,0.3);
  outline: none;
}

.game-cell {
  width: 25px;
  height: 25px;
  background: #ecf0f1;
  border-radius: 3px;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: all 0.2s ease;
  position: relative;
}

.game-cell.snake-head {
  background: #2ecc71 !important;
  border-radius: 50%;
  box-shadow: 0 0 10px rgba(46, 204, 113, 0.5);
  animation: pulse 1s infinite;
}

.game-cell.snake-body {
  background: #27ae60;
  border-radius: 8px;
}

.game-cell.food {
  background: #e74c3c;
  border-radius: 50%;
  animation: foodPulse 1s infinite;
}

.game-cell.wall {
  background: #34495e;
  border-radius: 0;
}

@keyframes pulse {
  0%, 100% { transform: scale(1); }
  50% { transform: scale(1.1); }
}

@keyframes foodPulse {
  0%, 100% { transform: scale(1); box-shadow: 0 0 5px rgba(231, 76, 60, 0.5); }
  50% { transform: scale(1.2); box-shadow: 0 0 15px rgba(231, 76, 60, 0.8); }
}

.snake-head-content {
  font-size: 16px;
  font-weight: bold;
  color: white;
}

.food-content {
  font-size: 18px;
  animation: rotate 2s linear infinite;
}

@keyframes rotate {
  from { transform: rotate(0deg); }
  to { transform: rotate(360deg); }
}

.game-overlay {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: rgba(0,0,0,0.8);
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 15px;
  backdrop-filter: blur(5px);
}

.overlay-content {
  text-align: center;
  background: rgba(255,255,255,0.1);
  padding: 40px;
  border-radius: 20px;
  backdrop-filter: blur(10px);
  border: 1px solid rgba(255,255,255,0.2);
}

.overlay-content h2 {
  font-size: 2.5em;
  margin-bottom: 20px;
  color: #f1c40f;
}

.overlay-content p {
  font-size: 1.2em;
  margin-bottom: 15px;
  color: #ecf0f1;
}

.new-record {
  color: #f1c40f !important;
  font-weight: bold;
  font-size: 1.5em !important;
  animation: celebration 1s infinite;
}

@keyframes celebration {
  0%, 100% { transform: scale(1); }
  50% { transform: scale(1.1); }
}

.game-over-stats {
  background: rgba(255,255,255,0.1);
  padding: 20px;
  border-radius: 10px;
  margin: 20px 0;
}

.game-over-stats div {
  margin: 5px 0;
  font-size: 1.1em;
}

.overlay-btn {
  padding: 15px 30px;
  border: none;
  border-radius: 25px;
  font-size: 18px;
  font-weight: 600;
  background: linear-gradient(45deg, #3498db, #2980b9);
  color: white;
  cursor: pointer;
  transition: all 0.3s ease;
  margin-top: 20px;
}

.overlay-btn:hover {
  transform: translateY(-2px);
  box-shadow: 0 5px 15px rgba(0,0,0,0.3);
}

.game-instructions {
  background: rgba(255,255,255,0.1);
  padding: 25px;
  border-radius: 15px;
  backdrop-filter: blur(10px);
  border: 1px solid rgba(255,255,255,0.2);
}

.game-instructions h3 {
  text-align: center;
  margin-bottom: 20px;
  font-size: 1.5em;
  color: #f1c40f;
}

.instructions-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: 15px;
}

.instruction-item {
  display: flex;
  align-items: center;
  gap: 15px;
  padding: 10px;
  background: rgba(255,255,255,0.05);
  border-radius: 10px;
}

.instruction-item .key {
  background: #34495e;
  color: white;
  padding: 8px 12px;
  border-radius: 8px;
  font-weight: bold;
  min-width: 50px;
  text-align: center;
  font-family: monospace;
}

.instruction-item .action {
  color: #ecf0f1;
}

.particles-container {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
  z-index: 1000;
}

.particle {
  position: absolute;
  border-radius: 50%;
}

/* 粒子动画 */
@keyframes particle-0 {
  to {
    transform: translate(20px, -20px);
    opacity: 0;
  }
}

@keyframes particle-1 {
  to {
    transform: translate(-20px, -20px);
    opacity: 0;
  }
}

@keyframes particle-2 {
  to {
    transform: translate(20px, 20px);
    opacity: 0;
  }
}

@keyframes particle-3 {
  to {
    transform: translate(-20px, 20px);
    opacity: 0;
  }
}

@keyframes particle-4 {
  to {
    transform: translate(30px, 0px);
    opacity: 0;
  }
}

@keyframes particle-5 {
  to {
    transform: translate(-30px, 0px);
    opacity: 0;
  }
}

@keyframes particle-6 {
  to {
    transform: translate(0px, 30px);
    opacity: 0;
  }
}

@keyframes particle-7 {
  to {
    transform: translate(0px, -30px);
    opacity: 0;
  }
}

/* 响应式设计 */
@media (max-width: 768px) {
  .snake-game-container {
    padding: 10px;
  }
  
  .game-header h1 {
    font-size: 2em;
  }
  
  .game-stats {
    gap: 15px;
  }
  
  .stat-item {
    padding: 10px 15px;
    font-size: 0.9em;
  }
  
  .game-controls {
    gap: 10px;
  }
  
  .control-btn {
    padding: 10px 20px;
    font-size: 14px;
  }
  
  .game-cell {
    width: 20px;
    height: 20px;
  }
  
  .instructions-grid {
    grid-template-columns: 1fr;
  }
}
</style>